package cn.iocoder.yudao.framework.dict.core.util;

import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.core.KeyValue;
import cn.iocoder.yudao.framework.common.util.cache.CacheUtils;
import cn.iocoder.yudao.module.system.api.dict.DictDataApi;
import cn.iocoder.yudao.module.system.api.dict.dto.DictDataRespDTO;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.time.Duration;
import java.util.ArrayList;
import java.util.List;

import static cn.iocoder.yudao.framework.common.util.cache.CacheUtils.buildAsyncReloadingCache;

/**
 * 字典工具类
 *
 * @author 芋道源码
 */
@Slf4j
public class DictFrameworkUtils {

    private static DictDataApi dictDataApi;

    private static final DictDataRespDTO DICT_DATA_NULL = new DictDataRespDTO();

    private static final List<String> LABEL_LIST_DICT_DATA_NULL = new ArrayList<>();

    private static final List<String> VALUE_LIST_DICT_DATA_NULL = new ArrayList<>();

    /**
     * 针对 {@link #getDictDataLabel(String, String)} 的缓存
     */
    private static final LoadingCache<KeyValue<String, String>, DictDataRespDTO> GET_DICT_DATA_CACHE = buildAsyncReloadingCache(
            Duration.ofMinutes(5L), // 过期时间 5 分钟
            new CacheLoader<KeyValue<String, String>, DictDataRespDTO>() {

                @Override
                public DictDataRespDTO load(KeyValue<String, String> key) {
                    return ObjectUtil.defaultIfNull(dictDataApi.getDictData(key.getKey(), key.getValue()).getCheckedData(),
                            DICT_DATA_NULL);
                }

            });

    /**
     * 针对 {@link #parseDictDataValue(String, String)} 的缓存
     */
    private static final LoadingCache<KeyValue<String, String>, DictDataRespDTO> PARSE_DICT_DATA_CACHE = buildAsyncReloadingCache(
            Duration.ofMinutes(5L), // 过期时间 5 分钟
            new CacheLoader<KeyValue<String, String>, DictDataRespDTO>() {

                @Override
                public DictDataRespDTO load(KeyValue<String, String> key) {
                    return ObjectUtil.defaultIfNull(dictDataApi.parseDictData(key.getKey(), key.getValue()).getCheckedData(),
                            DICT_DATA_NULL);
                }

            });

    /**
     * 针对 {@link #getLabelListByDictType(String, String)} 的缓存
     */
    private static final LoadingCache<KeyValue<String, String>, List<String>> LABEL_LIST_DICT_DATA_CACHE = buildAsyncReloadingCache(
            Duration.ofMinutes(5L), // 过期时间 30 分钟
            new CacheLoader<KeyValue<String, String>, List<String>>() {

                @Override
                public List<String> load(KeyValue<String, String> key) {
                    return (dictDataApi.getDictDataLabelList(key.getKey())!=null ? dictDataApi.getDictDataLabelList(key.getKey())//没有使用map入参的值查询
                            : LABEL_LIST_DICT_DATA_NULL);

                }
            });


    /**
     * 针对 {@link #getValueListByDictType(String, String)} 的缓存
     */
    private static final LoadingCache<KeyValue<String, String>, List<String>> VALUE_LIST_DICT_DATA_CACHE = buildAsyncReloadingCache(
            Duration.ofMinutes(5L), // 过期时间 30 分钟
            new CacheLoader<KeyValue<String, String>, List<String>>() {

                @Override
                public List<String> load(KeyValue<String, String> key) {
                    return (dictDataApi.getDictDataLabelList(key.getKey())!=null ? dictDataApi.getDictDataValueList(key.getKey())//没有使用map入参的值查询
                            : VALUE_LIST_DICT_DATA_NULL);

                }
            });


    public static void init(DictDataApi dictDataApi) {
        DictFrameworkUtils.dictDataApi = dictDataApi;
        log.info("[init][初始化 DictFrameworkUtils 成功]");
    }

    /**
     * 获取字典标签 根据字典类型和字典标签-是Integer类型的--从缓存中
     * @param dictType 字典类型
     * @param value 值Integer类型的
     * @return 字典标签
     */
    @SneakyThrows
    public static String getDictDataLabel(String dictType, Integer value) {
        return GET_DICT_DATA_CACHE.get(new KeyValue<>(dictType, String.valueOf(value))).getLabel();
    }

    /**
     * 获取字典标签根据字典类型和字典值
     * @param dictType 字典类型
     * @param value 值
     * @return 字典标签
     */
    @SneakyThrows
    public static String getDictDataLabel(String dictType, String value) {
        return GET_DICT_DATA_CACHE.get(new KeyValue<>(dictType, value)).getLabel();
    }

    /**
     * 获取字典标签的值根据字典类型和字典标签--从缓存中
     * @param dictType 字典类型
     * @param label 字典标签
     * @return 字典值
     */
    @SneakyThrows
    public static String parseDictDataValue(String dictType, String label) {
        return PARSE_DICT_DATA_CACHE.get(new KeyValue<>(dictType, label)).getValue();
    }

    /**
     * 获取字典标签list根据字典类型
     * @param dictType 字典类型
     * @return 字典标签list
     */
    @SneakyThrows
    public static List<String> getLabelListByDictType(String dictType,String defaultValue) {
        return LABEL_LIST_DICT_DATA_CACHE.get(new KeyValue<>(dictType, defaultValue));
    }

    /**
     * 获取字典值list根据字典类型
     * @param dictType 字典类型
     * @return 获取字典值list
     */
    @SneakyThrows
    public static List<String> getValueListByDictType(String dictType,String defaultValue) {
        return VALUE_LIST_DICT_DATA_CACHE.get(new KeyValue<>(dictType, defaultValue));
    }

}
